package cn.fcraft.utils;

public class Fraction {
    public int son;
    public int mom;

    /** @param son 分子
     * @param mom 分母
     */
    public Fraction(int son,int mom) {
        this.son = son;
        this.mom = mom;
    }

    /** @param num 一个整数
     */
    public Fraction(int num) {
        this.son = num;
        this.mom = 1;
    }

    /** 返回a为b的多少倍
     * @param a (较大的)整数
     * @param b (较小的)整数
     */
    public static Fraction getMultiple(int a,int b) {
        Fraction f = new Fraction(a,b);
        f.simplify();
        return f;
    }

    /** 取两个分数的乘积
     * @param a 乘数1
     * @param b 乘数2
     */
    public static Fraction multiply(Fraction a,Fraction b) {
        Fraction f = new Fraction(a.son * b.son,a.mom * b.mom);
        f.simplify();
        return f;
    }

    /** 取乘数1与乘数2相乘的结果
     * @param a 乘数1
     * @param b 乘数2的倒数
     */
    public static Fraction divide(Fraction a,Fraction b) {
        Fraction f = new Fraction(a.son * b.mom,a.mom * b.son);
        f.simplify();
        return f;
    }

    /** 取回分数所示的数值
     */
    public double getValue() {
        return (double)this.son/(double)this.mom;
    }

    /** 取分数所示数值的绝对值
     */
    public double getAbsValue() {
        return java.lang.Math.abs(getValue());
    }

    /** 取回简化后的分数数值
     */
    public double getSimplifiedValue() {
        simplify();
        return (double)this.son/(double)this.mom;
    }

    /** 简化分数
     */
    public void simplify() {
        int gcd = Math.getGcd(this.mom,this.son);
        this.son /= gcd;
        this.mom /= gcd;
        if ((this.son < 0 && this.mom < 0) || (this.son > 0 && this.mom <0)) {
            this.son = -this.son;
            this.mom = -this.mom;
        }
        if (this.son == 0) {
            this.mom = 1;
        }
    }

    /** 将一个整数加到分数上
     * @param num 一个整数
     */
    public void add(int num) {
        this.son += num * this.mom;
        simplify();
    }

    /** 将一个分数加到分数上
     * @param f 一个分数类
     */
    public void add(Fraction f) {
        this.son = this.son * f.mom + this.mom * f.son;
        this.mom *= f.mom;
        simplify();
    }

    /** 令该分数减去一个整数
     * @param num 一个整数
     */
    public void subtract(int num) {
        this.son -= num * this.mom;
        simplify();
    }

    /** 令该分数减去一个分数
     * @param f 一个分数类
     */
    public void subtract(Fraction f) {
        this.son = this.son * f.mom - this.mom * f.son;
        this.mom *= f.mom;
        simplify();
    }

    /** 令该分数乘上一个整数
     * @param num 一个整数
     */
    public void multiply(int num) {
        this.son *= num;
        simplify();
    }

    /** 令该分数乘上一个分数
     * @param f 一个分数类
     */
    public void multiply(Fraction f) {
        this.son *= f.son;
        this.mom *= f.mom;
        simplify();
    }

    /** 令该分数除去一个整数(分子乘以这个整数)
     * @param num 一个整数
     */
    public void divide(int num) {
        this.mom *= num;
        simplify();
    }

    /** 令该分数除去一个分数(乘以这个分数的倒数)
     * @param f 一个分数类
     */
    public void divide(Fraction f) {
        this.son *= f.mom;
        this.mom *= f.son;
        simplify();
    }
}
